import 'dart:async';

import 'BarrageModel.dart';
import 'hi_barrage.dart';
import 'package:flutter/material.dart';

import 'hi_barrage_track.dart';
import 'hi_socket.dart';

abstract class IBarrageStatus {
  void paused();

  void play();
}

class HiBarrageView extends StatefulWidget {
  final double? width;
  final double? height;
  final String vid;
  final bool autoPlay;
  final Map<String, dynamic> headers;

  const HiBarrageView(
      {super.key,
      required this.autoPlay,
      required this.width,
      required this.height,
      required this.headers,
      required this.vid});

  @override
  State<StatefulWidget> createState() {
    return HiBarrageViewState();
  }
}

class HiBarrageViewState extends State<HiBarrageView>
    with SingleTickerProviderStateMixin
    implements IBarrageStatus {
  List<BarrageModel> barrageCache = List.empty(growable: true);
  int barrageIndex = -1;
  List<Widget> barrages = List.empty(growable: true);
  Timer? _timer;
  HiSocket? _hiSocket;

  _play() {
    //有timer 正在运行，就不再重建
    if (_timer != null && (_timer?.isActive ?? false)) {
      return;
    }
    _playActual();
  }

  _playActual() {
    _timer = Timer.periodic(const Duration(milliseconds: 500), (timer) {
      if (barrageCache.isEmpty) {
        timer.cancel();
      } else {
        var barrage = barrageCache.removeAt(0);
        barrageIndex++;
        var barrageTrack = barrageIndex % 4;
        var top = 40.0;
        var trackHeight = 30;
        var barrageTrackHeight = top + trackHeight * barrageTrack;
        barrages.add(HiBarrageTrack(
            onComplete: (widget) {
              barrages.remove(widget);
            },
            top: barrageTrackHeight,
            speed: const Duration(seconds: 5),
            child: HiBarrage(
              priority: barrage.priority,
              barrage: barrage.content,
            )));
        setState(() {});
      }
    });
  }

  @override
  void dispose() {
    _hiSocket?.close();
    super.dispose();
  }

  @override
  void initState() {
    _timer?.cancel();
    super.initState();
    if (widget.autoPlay) {
      generateBarrage();
    }
  }

  void generateBarrage() async {
    _hiSocket = HiSocket(widget.headers);
    _hiSocket?.open(widget.vid).listen((message) {
      barrageCache.addAll(message);
      _play();
    });
  }

  @override
  Widget build(BuildContext context) {
    return SizedBox(
        width: widget.width,
        height: widget.height,
        child: Stack(
          children: [...barrages],
        ));
  }

  send(String? message) {
    if (message == null) return;
    _hiSocket?.send(message);
    barrageCache
        .add(BarrageModel(content: message, vid: '-1', priority: 1, type: 1));
    _play();
  }

  @override
  void paused() {
    _timer?.cancel();
    barrages.clear();
    setState(() {});
  }

  @override
  void play() {
    _playActual();
  }
}
